/*********************************************************************\
*
*                  (c) lkc
*                  All Rights Reserved. lkc Confidential
*
\*********************************************************************/
/*********************************************************************\
*   Title                      :
*
*   Module Description         :
*
*   Author                     : lkc
*
*   Created                    : 2018-11-1
*
\*********************************************************************/

#include <time.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "vpu.h"
#include "enc.h"
#include "utils_vpu.h"
#include "VedioRecord.h"


int open_files(struct cmd_line *cmd)
{
    cmd->dst_fd = open(cmd->output, O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
    if (cmd->dst_fd < 0) {
        perror("file open");
        return -1;
    }
    info_msg("Output file \"%s\" opened.\n", cmd->output);
    return 0;
}

void close_files(struct cmd_line *cmd)
{
    if ((cmd->dst_fd > 0)) {
        close(cmd->dst_fd);
        cmd->dst_fd = -1;
    }
}

int check_params(struct cmd_line *cmd)
{
    switch (cmd->format) {
    case STD_MPEG4:
        info_msg("Format: STD_MPEG4\n");
        switch (cmd->mp4_h264Class) {
        case 0:
            info_msg("MPEG4 class: MPEG4\n");
            break;
        case 1:
            info_msg("MPEG4 class: DIVX5.0 or higher\n");
            break;
        case 2:
            info_msg("MPEG4 class: XVID\n");
            break;
        case 5:
            info_msg("MPEG4 class: DIVX4.0\n");
            break;
        default:
            err_msg("Unsupported MPEG4 Class!\n");
            break;
        }
        break;
    case STD_H263:
        info_msg("Format: STD_H263\n");
        break;
    case STD_AVC:
        info_msg("Format: STD_AVC\n");
        switch (cmd->mp4_h264Class) {
        case 0:
            info_msg("AVC\n");
            break;
        case 1:
            info_msg("MVC\n");
            break;
        default:
            err_msg("Unsupported H264 type\n");
            break;
        }
        break;
    case STD_VC1:
        info_msg("Format: STD_VC1\n");
        break;
    case STD_MPEG2:
        info_msg("Format: STD_MPEG2\n");
        break;
    case STD_DIV3:
        info_msg("Format: STD_DIV3\n");
        break;
    case STD_RV:
        info_msg("Format: STD_RV\n");
        break;
    case STD_MJPG:
        info_msg("Format: STD_MJPG\n");
        break;
    case STD_AVS:
        info_msg("Format: STD_AVS\n");
        break;
    case STD_VP8:
        info_msg("Format: STD_VP8\n");
        break;
    default:
        err_msg("Unsupported Format!\n");
        break;
    }

    if (cmd->width == 0)
        cmd->width = 176; /* default */

    if (cmd->height == 0)
        cmd->height = 144;

    if (cmd->width % 16 != 0) {
        cmd->width -= cmd->width % 16;
        warn_msg("width not divisible by 16, adjusted %d\n",
                cmd->width);
    }

    if (cmd->height % 8 != 0) {
        cmd->height -= cmd->height % 8;
        warn_msg("height not divisible by 8, adjusted %d\n",
                cmd->height);
    }

    if (cmd->rot_en) {
        if (cmd->rot_angle != 0 && cmd->rot_angle != 90 &&
            cmd->rot_angle != 180 && cmd->rot_angle != 270) {
            warn_msg("Invalid rotation angle. No rotation!\n");
            cmd->rot_en = 0;
            cmd->rot_angle = 0;
        }
    }

    if (cmd->mirror < MIRDIR_NONE || cmd->mirror > MIRDIR_HOR_VER) {
        warn_msg("Invalid mirror angle. Using 0\n");
        cmd->mirror = 0;
    }

    if (!(cmd->format == STD_MPEG4 || cmd->format == STD_H263 ||
        cmd->format == STD_MPEG2 || cmd->format == STD_DIV3) &&
        cmd->deblock_en) {
        warn_msg("Deblocking only for MPEG4 and MPEG2. Disabled!\n");
        cmd->deblock_en = 0;
    }
    return 0;
}


int EncodeFun()
{
    struct cmd_line cmd = {0};
    printf("Start Encode\n");
    char fileName[100];
    memset(fileName,0,100) ;
    sprintf(fileName,"%d.264",time(NULL));

    cmd.deblock_en = 0;
    cmd.format = STD_AVC;
    cmd.mp4_h264Class = 0;
    cmd.width = 720;
    cmd.height = 576;
    cmd.fps = 25;
    cmd.count = 0;//若设置了大于0的数字N，则录制N帧后停止录制
//    strncpy(cmd.output, "test.264", MAX_PATH);
    strncpy(cmd.output, fileName, MAX_PATH);
    cmd.chromaInterleave = 1;

    cmd.mapType = LINEAR_FRAME_MAP;

    vpu_test_dbg_level = 2;
    info_msg("VPU test program built on %s %s\n", __DATE__, __TIME__);

    LockVedioRecord();

    int err = vpu_Init(NULL);
    if (err)
    {
        err_msg("VPU Init Failure.\n");
        return -1;
    }

    vpu_versioninfo ver;
    err = vpu_GetVersionInfo(&ver);
    if (err)
    {
        err_msg("Cannot get version info, err:%d\n", err);
        vpu_UnInit();
        return -1;
    }
    info_msg("VPU firmware version: %d.%d.%d_r%d\n", ver.fw_major, ver.fw_minor,ver.fw_release, ver.fw_code);
    info_msg("VPU library version: %d.%d.%d\n", ver.lib_major, ver.lib_minor, ver.lib_release);

    int ret = 0;
    if(check_params(&cmd) == 0)
    {
        if(open_files(&cmd) == 0)
        {
            ret = encode_process(&cmd);
            printf("stop encode_process and close file\n");
            close_files(&cmd);
        }
    }
    vpu_UnInit();
    printf("Stop Record\n");
    UnLockVedioRecord();
    return ret;
}

/********************************************************************\
 *
 * REVISION RECORDS
 *
\*********************************************************************/
/*********************************************************************/
/*
 *
 *
 *
\*********************************************************************/
/*------------------------------The End------------------------------*/
